home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 1 (Walnut Creek)
/
Aminet - June 1993 [Walnut Creek].iso
/
aminet
/
gfx
/
conv
/
ilbm24.lha
/
ilbm
/
readilbm.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-02-12
|
6KB
|
180 lines
/*
* read.c 24 bit IFF ILBM -> 24 bit Sun Raster
* ILBM's can be compressed or uncompressed, only uncompressed
* Sun Rasters are written. By Brett Van Sprewenburg
*
* Credit to the ppm utilities, the developer(s) of xv, and Commodore-Amiga for
* code and ideas.
*
* This whole thing is a bit of a hack...
*
* Version Date
* 1.0 12/??/92 Initial attempts to read the 24 bit IFF ILBM format
* 1.1 2/4/93 Cleaned code, fixed bugs with read and writeilbm intergration
* 1.2 2/9/93 ANSI'fied code some more for compilation with acc
* 1.2.1 2/10/93 Checks to make sure it's a valid iff file, looks for FORM chuck id
* Fixed a couple of minor printf bugs.
* 1.2.2 2/11/93 Checks to make sure that there are 24 bit planes in the IFF.
* 1.2.3 2/12/93 Checked that mallocs actually got what they wanted.
* First public release
*/
#include <readilbm.h>
int ReadILBM(char *, char *);
int ReadILBM(char *ilbmfile,char *rasterfile)
{
unsigned char form[5];
unsigned char *ubp,*bp,*runbuf;
unsigned char *Rrow;
unsigned char *Brow;
unsigned char *Grow;
unsigned int byte;
int fd,totbytes,bytes,row,col,plane,j,subtotal;
long bmsize,formsize;
unsigned char *body = 0;
unsigned long body_chunk_size;
if ((fp = fopen(ilbmfile,"r")) == NULL) {
fprintf(stderr,"Open of '%s' for reading failed.\n",ilbmfile);
return -1;
}
if ((fd = creat(rasterfile,0660)) < 0) {
fprintf(stderr,"Open of '%s' for writing failed.\n",rasterfile);
return -1;
}
fread(form,4,1,fp); /* FORM */
if (strcmp(form,"FORM") != NULL) {
fprintf(stderr,"'%s' is not an IFF file. Exiting.\n",ilbmfile);
fclose(fp);
close(fd);
return -2;
}
fread(&formsize,4,1,fp); /* Size of whole form -4 */
printf("%s ",form);
fread(form,4,1,fp); /* ILBM */
printf("%s: (%d bytes) ",form,formsize);
fread(form,4,1,fp); /* BMHD */
fread(&bmsize,4,1,fp); /* size of BMHD */
fread(&ilbmheader,20,1,fp);
printf("(%dx%d) (%d planes) (Compression %s)\n",ilbmheader.w,ilbmheader.h,ilbmheader.nPlanes, ilbmheader.compression == cmpByteRun1 ? "On" : "Off");
if (ilbmheader.nPlanes != 24) {
fprintf(stderr,"Only IFF ILBM's of 24 bit planes are supported.\n");
fclose(fp);
close(fd);
return -3;
}
fread(form,4,1,fp); /* BODY (ANNO sometimes) */
while ((strcmp(form,"BODY") != 0)) /* Find the damn thing */
fread(form,4,1,fp);
fread(&body_chunk_size,4,1,fp);
pixelrow = ALLOCROW(ilbmheader.w);
body = (unsigned char*) malloc(body_chunk_size);
runbuf = (unsigned char*) malloc(RowBytes(ilbmheader.w));
Rrow = (unsigned char*) malloc(ilbmheader.w);
Grow = (unsigned char*) malloc(ilbmheader.w);
Brow = (unsigned char*) malloc(ilbmheader.w);
if (body == NULL || pixelrow == NULL || runbuf == NULL ||
Rrow == NULL || Grow == NULL || Brow == NULL) {
fprintf(stderr,"Unable to allocate all the memory I need...\n");
fclose(fp);
close(fd);
return -4;
}
bp = body;
/* Define and write the Sun Raster header */
sunheader.ras_magic = RAS_MAGIC;
sunheader.ras_width = ilbmheader.w;
sunheader.ras_height = ilbmheader.h;
sunheader.ras_depth = ilbmheader.nPlanes;
sunheader.ras_length = ilbmheader.h * ilbmheader.w * 3;
sunheader.ras_type = RT_FORMAT_RGB;
sunheader.ras_maptype = RMT_NONE;
sunheader.ras_maplength = 0;
write(fd, sunheader, sizeof(sunheader));
/* Read in the body of the ilbm */
fread(body, body_chunk_size, 1, fp);
for (row = 0; row < (int)ilbmheader.h; row++ ) {
/* There are kind of colormappish */
for (col = 0; col < (int)ilbmheader.w ; col++ )
Rrow[col] = Grow[col] = Brow[col] = 0;
for(plane = 0; plane < (int)ilbmheader.nPlanes; plane++) {
switch (ilbmheader.compression) {
case 0:
ubp = bp;
bp += RowBytes((int)ilbmheader.w);
break;
case 1:
ubp = runbuf;
totbytes = RowBytes((int)ilbmheader.w);
do {
byte = *bp++;
if ( byte <= 127 )
for ( j = byte, totbytes -= j + 1; j >= 0; j--) {
*ubp++ = *bp++;
}
else if ( byte != 128 )
for (j = 256 - byte, totbytes -= j + 1, byte = *bp++; j >= 0; j--) {
*ubp++ = byte;
}
} while ( totbytes > 0 );
ubp = runbuf;
break;
}
/* Break raw row buffer up into separate rgb values */
/* In order to understand this a little better, it might help */
/* to know that the pixel values in an ILBM appear to be stored */
/* bit reversed. Hence all the logical bitwise juju. */
for ( col = 0; col < (int)ilbmheader.w; col++ )
if ( plane < 8 )
{ /* red */
if ( ubp[col / 8] & ( 128 >> ( col % 8 ) ) )
Rrow[col] |= 1 << plane;
}
else if ( plane > 15 )
{ /* blue */
if ( ubp[col / 8] & ( 128 >> ( col % 8 ) ) )
Brow[col] |= 1 << (plane-16);
}
else
{ /* green */
if ( ubp[col / 8] & ( 128 >> ( col % 8 ) ) )
Grow[col] |= 1 << (plane-8);
}
}
/* Get the rgb values out of pixel structure, pointed at by pixelrow */
for ( col = 0; col < (int)ilbmheader.w; col++ )
ASSIGN(pixelrow[col],Rrow[col],Grow[col],Brow[col]);
/* Write out an entire row of pixel interleaved data */
write(fd, pixelrow, (int)ilbmheader.w * 3);
}
free(Rrow); /* Fly! Be Free!! */
free(Grow);
free(Brow);
free(runbuf);
free(pixelrow);
free(body);
fclose(fp);
close(fd);
return 0;
}